package ldh.maker.component;

import com.google.gson.Gson;
import com.jfoenix.controls.JFXCheckBox;
import com.jfoenix.controls.JFXTextField;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import ldh.database.Column;
import ldh.database.Table;
import ldh.maker.database.TableInfo;
import ldh.maker.db.TableViewDb;
import ldh.maker.util.DbInfoFactory;
import ldh.maker.vo.TableViewData;
import ldh.maker.vo.TreeNode;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by ldh123 on 2018/5/6.
 */
public class PojoTableUi extends BaseSettingTabPane {

    private Map<String, TextField> textFieldMap = new HashMap<>();
    private Map<String, CheckBox> checkBoxMap = new HashMap<>();
    private String tableName = null;

    public PojoTableUi(TreeItem<TreeNode> treeItem, String dbName) {
        super(treeItem, dbName);
    }

    protected String getTitle() {
        return "设置表需要显示的字段和宽度";
    }

    protected Node initBody() {
        VBox vBox = new VBox();
        vBox.setSpacing(10);
        vBox.getStyleClass().add("round-border");

        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setFitToHeight(true);
        scrollPane.setFitToWidth(true);

        FlowPane tablePane = new FlowPane();
        tablePane.setVgap(5); tablePane.setHgap(10);
        tablePane.setPadding(new Insets(5, 5, 5, 5));
        scrollPane.setContent(tablePane);

        GridPane columnPane = new GridPane();
        columnPane.setVgap(5); columnPane.setHgap(10);
        columnPane.setCache(false);

        ScrollPane columnScrollPane = new ScrollPane();
        columnScrollPane.setFitToHeight(true);
        columnScrollPane.setFitToWidth(true);
        columnScrollPane.setContent(columnPane);

        SplitPane splitPane = new SplitPane();
        splitPane.setOrientation(Orientation.VERTICAL);
        splitPane.getItems().addAll(scrollPane, columnScrollPane);

        TableView tableView = new TableView();
        tableView.setPrefHeight(50);

        TableInfo tableInfo = DbInfoFactory.getInstance().get(treeItem.getValue().getParent().getId() + "_" + dbName);
        for(Map.Entry<String, Table> entry : tableInfo.getTables().entrySet()) {
            Table table = entry.getValue();
            if (table.getPrimaryKey() == null || !table.isCreate()) continue;
            Label label = new Label(table.getJavaName());
            label.setPrefWidth(160);
            label.setOnMouseClicked(e->{
                tableName =entry.getKey();
                buildColumnPane(table, columnPane, tableView);
                addCss(label);
            });
            tablePane.getChildren().add(label);
        }

        VBox.setVgrow(splitPane, Priority.ALWAYS);
        vBox.getChildren().addAll(splitPane, new Separator(), tableView);
        return vBox;
    }

    private void addCss(Label label) {
        Pane gridPane = (Pane) label.getParent();
        for (Node node : gridPane.getChildren()) {
            node.getStyleClass().remove("label_active");
        }
        label.getStyleClass().add("label_active");
    }

    private void buildColumnPane(Table table, GridPane columnPane, TableView tableView) {
        columnPane.getChildren().clear();
        tableView.getColumns().clear();
        textFieldMap.clear();
        checkBoxMap.clear();

        TableInfo tableInfo = DbInfoFactory.getInstance().get(treeItem.getValue().getParent().getId() + "_" + dbName);
        Map<String, TableViewData> tableViewDataMap = tableInfo.getTableViewDataMap();
        if (tableName == null) return;
        TableViewData currentTableViewData = tableViewDataMap.get(tableName);
        List<TableViewData.ColumnData> columnDatas = null;
        if (currentTableViewData != null) {
            columnDatas = currentTableViewData.getColumnDatas();
        }

        List<Column> columns = table.getColumnList();
        int cidx = 0, ridx = 0;
        int i = 0;
        for (Column column : columns) {
            CheckBox checkBox = new JFXCheckBox(column.getName());
            checkBox.setSelected(true);
            Label label = new Label("宽度");
            TextField width = new JFXTextField();
            width.setPromptText("默认宽度");
            GridPane.setConstraints(checkBox, cidx++, ridx);
            GridPane.setConstraints(label, cidx++, ridx);
            GridPane.setConstraints(width, cidx++, ridx);
            columnPane.getChildren().addAll(checkBox, label, width);

            textFieldMap.put(column.getName(), width);
            checkBoxMap.put(column.getName(), checkBox);

            TableColumn tableColumn = new TableColumn(column.getName());
            tableColumn.setUserData(column.getName());
            tableView.getColumns().add(tableColumn);

            int idx = i;
            checkBox.selectedProperty().addListener((b, o, n)->{
                if (!n) {
                    tableView.getColumns().remove(tableColumn);
                } else {
                    tableView.getColumns().add(idx, tableColumn);
                }
            });

            width.textProperty().addListener((b, o, n)->{
                int columnWidth = 0;
                try {
                    columnWidth = Integer.parseInt(n);
                } catch (Exception e) {}
                if (columnWidth > 0) {
                    tableColumn.setPrefWidth(columnWidth);
                }
            });

            if (columnDatas != null) {
                for (TableViewData.ColumnData columnData : columnDatas) {
                    if (columnData.getColumnName().equals(column.getName())) {
                        if (columnData.getWidth() != null) {
                            width.setText(columnData.getWidth() + "");
                            tableColumn.setPrefWidth(columnData.getWidth());
                        }
                        checkBox.setSelected(columnData.getShow());
                    }
                }
            }

            if (cidx == 9) {
                cidx = 0;
                ridx++;
            }
            i++;
        }
        columnPane.getColumnConstraints().clear();
        columnPane.getColumnConstraints().addAll(buildNode(100), buildNode(30), buildNode(100)
            , buildNode(100), buildNode(30), buildNode(100), buildNode(100), buildNode(30), buildNode(100));
    }

    protected void save(ActionEvent event) {
        if(!check()) return;
        TableInfo tableInfo = DbInfoFactory.getInstance().get(treeItem.getValue().getParent().getId() + "_" + dbName);
        Map<String, TableViewData> tableViewDataMap = tableInfo.getTableViewDataMap();
        if (tableName == null) return;
        TableViewData currentTableViewData = tableViewDataMap.get(tableName);
        List<TableViewData.ColumnData> columnDatas = new ArrayList<>();
        for(Column colmun : tableInfo.getTable(tableName).getColumnList()) {
            TableViewData.ColumnData columnData = new TableViewData.ColumnData();
            TextField textFiled = textFieldMap.get(colmun.getName());
            if (!StringUtils.isEmpty(textFiled.getText().trim())) {
                columnData.setWidth(Integer.parseInt(textFiled.getText().trim()));
            }
            CheckBox checkBox = checkBoxMap.get(colmun.getName());
            columnData.setShow(checkBox.isSelected());
            columnData.setColumnName(colmun.getName());
            columnDatas.add(columnData);
        }

        Gson gson = new Gson();
        String json = gson.toJson(columnDatas);
        if (currentTableViewData == null) {
            currentTableViewData = new TableViewData();
            currentTableViewData.setTreeNodeId(treeItem.getValue().getParent().getId());
            currentTableViewData.setDbName(dbName);
            currentTableViewData.setTableName(tableName);
            tableViewDataMap.put(tableName, currentTableViewData);
        }
        currentTableViewData.setColumns(json);

        TableViewData data = currentTableViewData;
        new Thread(new Task<Void>() {

            @Override
            protected Void call() throws Exception {
                TableViewDb.save(data);
                return null;
            }
        }).start();
    }

    protected boolean check() {
        return true;
    }

    protected void reset(ActionEvent event) {
        TableInfo tableInfo = DbInfoFactory.getInstance().get(treeItem.getValue().getParent().getId() + "_" + dbName);
        Map<String, TableViewData> tableViewDataMap = tableInfo.getTableViewDataMap();
        if (tableName == null) return;
        TableViewData tableViewData = tableViewDataMap.get(tableName);
        if (tableViewData == null) return;
        List<TableViewData.ColumnData> columnDatas = tableViewData.getColumnDatas();
        for (TableViewData.ColumnData columnData : columnDatas) {
            TextField textField = textFieldMap.get(columnData.getColumnName());
            if (textField != null) {
                textField.setText(columnData.getWidth() + "");
            }
            CheckBox checkBox = checkBoxMap.get(columnData.getColumnName());
            if (checkBox != null) {
                checkBox.setSelected(columnData.getShow());
            }
        }
    }

    protected void clean(ActionEvent event) {
        for(Map.Entry<String, TextField> entry : textFieldMap.entrySet()) {
            entry.getValue().setText("");
        }
        for(Map.Entry<String, CheckBox> entry : checkBoxMap.entrySet()) {
            entry.getValue().setSelected(false);
        }
    }

}
